﻿using System;
using TestWebApplication.CommercePaymentInstrument.APIs;
using Microsoft.Commerce.Proxy.PaymentInstrumentService;
using System.ServiceModel;
using System.Security;
using System.Security.Cryptography.X509Certificates;

namespace TestWebApplication.CommercePaymentInstrument
{

    public class CommercePaymentInstrumentServiceAdapter : ServiceAdapter
    {
        private const string CommerceContractName = "Microsoft.Commerce.Proxy.PaymentInstrumentService";

        public CommercePaymentInstrumentServiceAdapter(string serviceUrl, X509Certificate2 cert)
            : base(serviceUrl, cert)
        {
        }

        /*public string TestConnection(string input)
        {
            CommercePaymentInstrumentTestConnectionApi api = new CommercePaymentInstrumentTestConnectionApi(this.binding, this.address, this.clientCert, input);

            if (api.Execute() == null)
            {
                return api.OutputString;
            }

            return null;
        }

        public KeySetKey Getkey(Guid keyGuid)
        {
            CommercePaymentInstrumentGetKeyApi api = new CommercePaymentInstrumentGetKeyApi(this.binding, this.address, this.clientCert, keyGuid);

            if (api.Execute() == null)
            {
                return api.Key;
            }

            return null;
        }*/

        public AddPaymentInstrumentOutput AddPaymentInstrument(CallerInfo callerInfo, PaymentInstrument piInfo)
        {
            AddPaymentInstrumentInput input = PrepareAddPIInput(callerInfo, piInfo);

            ChannelFactory<PaymentInstrumentServiceChannel> clientFactory = new ChannelFactory<PaymentInstrumentServiceChannel>(this.binding, this.address);

            clientFactory.Endpoint.Contract.Name = CommerceContractName;
            clientFactory.Credentials.ClientCertificate.Certificate = this.clientCert;
            PaymentInstrumentServiceChannel channel = clientFactory.CreateChannel();

            AddPaymentInstrumentOutput output = channel.AddPaymentInstrument(input);


            return output;
        }

        /*public CommerceAddPaymentInstrumentResult ResumeAddPaymentInstrument(Phase lastPhase)
        {
            CommerceResumeAddPaymentInstrumentApi api = new CommerceResumeAddPaymentInstrumentApi(this.binding, this.address, this.clientCert, lastPhase);

            if (api.Execute())
            {
                return api.AddPIResult;
            }

            return null;
        }*/

        /*public PaymentInstrument UpdatePaymentInstrument(CallerInfo callerInfo, PaymentInstrument piInfo)
        {
            CommerceUpdatePaymentInstrumentApi api = new CommerceUpdatePaymentInstrumentApi(this.binding, this.address, this.clientCert, callerInfo, piInfo);
            if (api.Execute() == null)
            {
                return api.PaymentInstrumentInfo;
            }

            return null;
        }*/

        public GetPaymentInstrumentsOutput GetPaymentInstruments(CallerInfo callerInfo, string paymentMethodId)
        {
            GetPaymentInstrumentsInput input = PrepareGetPIInput(callerInfo, paymentMethodId);

            ChannelFactory<PaymentInstrumentServiceChannel> clientFactory = new ChannelFactory<PaymentInstrumentServiceChannel>(this.binding, this.address);

            clientFactory.Endpoint.Contract.Name = CommerceContractName;
            clientFactory.Credentials.ClientCertificate.Certificate = this.clientCert;
            PaymentInstrumentServiceChannel channel = clientFactory.CreateChannel();

            GetPaymentInstrumentsOutput output = channel.GetPaymentInstruments(input);


            return output;
        }

        public GetGlobalPaymentInstrumentsOutput GetGlobalPaymentInstruments(CallerInfo callerInfo, string countryCode, string partner)
        {
            GetGlobalPaymentInstrumentsInput input = PrepareGetGlobalPIInput(callerInfo, countryCode, partner);

            ChannelFactory<PaymentInstrumentServiceChannel> clientFactory = new ChannelFactory<PaymentInstrumentServiceChannel>(this.binding, this.address);
            
            clientFactory.Endpoint.Contract.Name = CommerceContractName;
            clientFactory.Credentials.ClientCertificate.Certificate = this.clientCert;
            PaymentInstrumentServiceChannel channel = clientFactory.CreateChannel();

            GetGlobalPaymentInstrumentsOutput output = channel.GetGlobalPaymentInstruments(input);


            return output;
        }

        /*public bool RemovePaymentInstrument(CallerInfo callerInfo, string paymentMethodId)
        {
            CommerceRemovePaymentInstrumentApi api = new CommerceRemovePaymentInstrumentApi(this.binding, this.address, this.clientCert, callerInfo, paymentMethodId);

            return api.Execute();
        }*/

        public AddPaymentInstrumentInput PrepareAddPIInput(CallerInfo callerInfo, PaymentInstrument piInfo)
        {
            AddPaymentInstrumentInput input = new AddPaymentInstrumentInput()
            {
                APIContext = new APIContext()
                {
                    TrackingGuid = new Guid()
                },

                CallerInfo = callerInfo,
                PaymentInstrument = piInfo,
            };

            return input;
        }

        public GetPaymentInstrumentsInput PrepareGetPIInput(CallerInfo callerInfo, string paymentMethodId)
        {
            GetPaymentInstrumentsInput input = new GetPaymentInstrumentsInput()
            {
                APIContext = new APIContext()
                {
                    TrackingGuid = new System.Guid(),
                },
                CallerInfo = callerInfo,
                PaymentMethodID = paymentMethodId
            };

            return input;
        }

        public GetGlobalPaymentInstrumentsInput PrepareGetGlobalPIInput(CallerInfo callerInfo, string countryCode, string partner)
        {
            GetGlobalPaymentInstrumentsInput input = new GetGlobalPaymentInstrumentsInput()
            {
                AccountId = callerInfo.AccountId,
                CountryCode = countryCode,
                OnBehalfOfPartner = new System.Guid(partner)
            };

            return input;
        }
    }
}
